home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / SNIP9_91.ARJ / POSIXDIR.C < prev    next >
C/C++ Source or Header  |  1991-09-12  |  10KB  |  270 lines

  1. /*
  2. **  POSIXDIR.C - POSIX-style directory processing
  3. */
  4.  
  5. #include <string.h>
  6. #include <stdlib.h>
  7. #include <dos.h>
  8. #include <io.h>
  9. #include <errno.h>
  10. #include "dirent.h"
  11.  
  12. #define _NDIRS 20
  13. #define SUCCESS 0
  14. #define ERROR  -1
  15.  
  16. #define LAST_CHAR(s) ((char *)(s))[strlen(s) - 1]
  17.  
  18. int DFerr;
  19. DOS_DIR _DIRS[_NDIRS];  /* Initilize DOS_DIR array to zeros     */
  20.  
  21. /*
  22. **  Convert Unix-style pathnames to DOS-style
  23. */
  24.  
  25. static char *unix2dos(char *path)
  26. {
  27.       char *p;
  28.  
  29.       while (NULL != (p = strchr(path, '/')))
  30.             *p = '\\';
  31.       return path;
  32. }
  33.  
  34. /****************************************************************/
  35. /*                                                              */
  36. /*  opendir()                                                   */
  37. /*                                                              */
  38. /*  Function: Open a directory for reading.                     */
  39. /*                                                              */
  40. /*  Parameters: 1 - Directory name. May include path spec.      */
  41. /*                                                              */
  42. /*  Returns: Pointer to a DOS_DIR typedef'ed structure, similar */
  43. /*           to fopen() returning a FILE pointer.               */
  44. /*                                                              */
  45. /*           NULL if error, DFerr set as follows:               */
  46. /*           SUCCESS - No error                                 */
  47. /*           ENOENT  - Could not locate directory or contents   */
  48. /*           ENOTDIR - Not a directory                          */
  49. /*           ENOMEM  - Too many directories already open        */
  50. /*                                                              */
  51. /*  Side effects: The dd_size element of the DOS_DIR structure  */
  52. /*                will contain a number representing the total  */
  53. /*                number of entries in the directory. The       */
  54. /*                dd_loc element will be set to zero since      */
  55. /*                no elements have, as yet, been read.          */
  56. /*                                                              */
  57. /****************************************************************/
  58.  
  59. DOS_DIR *opendir(char *fname)
  60. {
  61.       int i;
  62.       unsigned n = 0;
  63.       char nametmp[13], *p;
  64.       struct DSTRUCT dstruct;
  65.  
  66.       for (i = 0; i < _NDIRS; ++i)
  67.       {
  68.             if (!_DIRS[i].dd_fd)
  69.                   break;
  70.       }
  71.       if (_NDIRS <= i)
  72.       {
  73.             DFerr = ENOMEM;
  74.             return NULL;
  75.       }
  76.  
  77.       unix2dos(fname);
  78.       if (':' == fname[1] && 1 < strlen(fname))
  79.             p = &fname[2];
  80.       else  p = fname;
  81.       while ('\\' == LAST_CHAR(p) && 1 < strlen(p))
  82.             LAST_CHAR(p) = '\0';
  83.         
  84.       if (strcmp(p, "\\") && strlen(p))
  85.       {
  86.             if (NULL == (rfind_1st(fname, FA_ANY, &_DIRS[i].dd_buf)))
  87.             {
  88.                   DFerr = ENOENT;
  89.                   return NULL;
  90.             }
  91.             if (!(FA_DIREC & _DIRS[i].dd_buf.ATTRIBUTE))
  92.             {
  93.                   DFerr = ENOTDIR;
  94.                   return NULL;
  95.             }
  96.       }
  97.       strcpy(_DIRS[i].dd_dirname, fname);
  98.       if (!strlen(p))
  99.             strcat(_DIRS[i].dd_dirname, ".");
  100.       if ('\\' != LAST_CHAR(_DIRS[i].dd_dirname))
  101.             strcat(_DIRS[i].dd_dirname, "\\");
  102.       strcat(strupr(_DIRS[i].dd_dirname), "*.*");
  103.       if (NULL == rfind_1st(_DIRS[i].dd_dirname, FA_ANY, &_DIRS[i].dd_buf))
  104.       {
  105.             DFerr = ENOENT;
  106.             return NULL;
  107.       }
  108.       memcpy(&dstruct, &_DIRS[i].dd_buf, sizeof(struct DSTRUCT));
  109.       do
  110.       {
  111.             ++n;
  112.       } while (rfind_nxt(&_DIRS[i].dd_buf));
  113.       memcpy(&_DIRS[i].dd_buf, &dstruct, sizeof(struct DSTRUCT));
  114.       _DIRS[i].dd_size = n;
  115.       _DIRS[i].dd_loc  = 0;
  116.       _DIRS[i].dd_fd   = i + 1;
  117.       DFerr = SUCCESS;
  118.       return &_DIRS[i];
  119. }
  120.  
  121. /****************************************************************/
  122. /*                                                              */
  123. /*  closedir()                                                  */
  124. /*                                                              */
  125. /*  Function: Close a preeviously opened directory.             */
  126. /*                                                              */
  127. /*  Parameters: 1 - DOS_DIR pointer of directory to close.      */
  128. /*                                                              */
  129. /*  Returns: SUCCESS or ERROR.                                  */
  130. /*                                                              */
  131. /****************************************************************/
  132.  
  133. int closedir(DOS_DIR *dirp)
  134. {
  135.       if (0 == dirp->dd_fd || _NDIRS < dirp->dd_fd)
  136.       {
  137.             DFerr = EBADF;
  138.             return ERROR;
  139.       }
  140.       memset(dirp, 0, sizeof(DOS_DIR));
  141.       return SUCCESS;
  142. }
  143.  
  144. /****************************************************************/
  145. /*                                                              */
  146. /*  rewinddir()                                                 */
  147. /*                                                              */
  148. /*  Function: Reset an open DOS_DIR to its first entry.         */
  149. /*                                                              */
  150. /*  Parameters: 1 - DOS_DIR pointer of directory to rewind.     */
  151. /*                                                              */
  152. /*  Returns: SUCCESS or ERROR.                                  */
  153. /*                                                              */
  154. /****************************************************************/
  155.  
  156. int rewinddir(DOS_DIR *dirp)
  157. {
  158.       if (0 == dirp->dd_fd || _NDIRS < dirp->dd_fd)
  159.       {
  160.             DFerr = EBADF;
  161.             return ERROR;
  162.       }
  163.       rfind_1st(dirp->dd_dirname, FA_ANY, &(dirp->dd_buf));
  164.       dirp->dd_loc = 0;
  165.       return SUCCESS;
  166. }
  167.  
  168. /****************************************************************/
  169. /*                                                              */
  170. /*  seekdir()                                                   */
  171. /*                                                              */
  172. /*  Function: Point to a selected entry in a DOS_DIR.           */
  173. /*                                                              */
  174. /*  Parameters: 1 - DOS_DIR pointer of directory to rewind.     */
  175. /*              2 - Offset of entry to seek                     */
  176. /*              3 - Origin of offset                            */
  177. /*                                                              */
  178. /*  Returns: A DSTRUCT pointer, same as returned by rfind_1st() */
  179. /*           and rfind_nxt().                                   */
  180. /*                                                              */
  181. /*           NULL if error, DFerr set as follows:               */
  182. /*           SUCCESS - No error                                 */
  183. /*           EBADF   - Bad file (DOS_DIR) pointer               */
  184. /*           EACCES  - Illegal origin specification             */
  185. /*           EOF     - Attempt to seek past end of directory    */
  186. /*                                                              */
  187. /****************************************************************/
  188.  
  189. struct DSTRUCT *seekdir(DOS_DIR *dirp, int offset, int origin)
  190. {
  191.       int i, loc;
  192.  
  193.       if (0 == dirp->dd_fd || _NDIRS < dirp->dd_fd)
  194.       {
  195.             DFerr = EBADF;
  196.             return NULL;
  197.       }
  198.       switch (origin)
  199.       {
  200.       case SEEK_SET:
  201.             loc = offset + 1;
  202.             break;
  203.       case SEEK_CUR:
  204.             loc = dirp->dd_loc + offset;
  205.             break;
  206.       case SEEK_END:
  207.             loc = dirp->dd_size + offset;
  208.             break;
  209.       default:
  210.             DFerr = EACCES;
  211.             return NULL;
  212.       }
  213.  
  214.       if (loc > (int)dirp->dd_size || 0 >= loc)
  215.       {
  216.             DFerr = EOF;
  217.             return NULL;
  218.       }
  219.  
  220.       rewinddir(dirp);
  221.       for (i = 0; i < loc; ++i)
  222.             readdir(dirp);
  223.  
  224.       DFerr = SUCCESS;
  225.       return (&(dirp->dd_buf));
  226. }
  227.  
  228. /****************************************************************/
  229. /*                                                              */
  230. /*  readdir()                                                   */
  231. /*                                                              */
  232. /*  Function: Reads entries from an open directory.             */
  233. /*                                                              */
  234. /*  Parameters: 1 - DOS_DIR pointer of directory to read.       */
  235. /*                                                              */
  236. /*  Returns: A DSTRUCT pointer, same as returned by rfind_1st() */
  237. /*           and rfind_nxt().                                   */
  238. /*                                                              */
  239. /*           NULL if error, DFerr set as follows:               */
  240. /*           SUCCESS - No error                                 */
  241. /*           EBADF   - Bad file (DOS_DIR) pointer               */
  242. /*           EOF     - Attempt to read past end of directory    */
  243. /*                                                              */
  244. /*  Side effects: The dd_loc element of the DOS_DIR structure   */
  245. /*                will contain a number representing which      */
  246. /*                element of the directory was returned. It may */
  247. /*                range from 1 to dd_size.                      */
  248. /*                                                              */
  249. /****************************************************************/
  250.  
  251. struct DSTRUCT *readdir(DOS_DIR *dirp)
  252. {
  253.       if (0 == dirp->dd_fd || _NDIRS < dirp->dd_fd)
  254.       {
  255.             DFerr = EBADF;
  256.             return NULL;
  257.       }
  258.       if (0 == dirp->dd_loc || NULL != rfind_nxt(&(dirp->dd_buf)))
  259.       {
  260.             dirp->dd_loc += 1;
  261.             DFerr = SUCCESS;
  262.             return (&(dirp->dd_buf));
  263.       }
  264.       else
  265.       {
  266.             DFerr = EOF;
  267.             return NULL;
  268.       }
  269. }
  270.